//==================================================================
//  Copyright (C) 2006-2007  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
/// @file	psys_string.cpp
///
/// Basic OS services.
///
//==================================================================

#include <windows.h>
#include "psys.h"
#include "psys_string.h"

//==================================================================
namespace PSYS {

//==================================================================
void StrRemoveBeginendSpaces( char *s )
{
	int		len = strlen( s );

	for (int i=0; i < len; ++i)
	{
		if ( s[i] != ' ' )	// head previous spaces
		{
			char	*desp = s;
			char	*last_nonspace_char_ptr = s;

			for (; i < len; ++i)	// copy to the end
			{
				if ( s[i] != ' ' )	// take note of last non-space (it's always != NULL !)
					last_nonspace_char_ptr = desp;

				*desp++ = s[i];
			}

			last_nonspace_char_ptr[1] = 0;	// put a string terminator right after
		}
	}
}

//==================================================================
void TStrRemoveBeginendSpaces( TCHAR *s )
{
	size_t		len = _tcslen( s );

	for (size_t i=0; i < len; ++i)
	{
		if ( s[i] != _TXCHAR(' ') )	// head previous spaces
		{
			TCHAR	*desp = s;
			TCHAR	*last_nonspace_char_ptr = s;

			for (; i < len; ++i)	// copy to the end
			{
				if ( s[i] != _TXCHAR(' ') )	// take note of last non-space (it's always != NULL !)
					last_nonspace_char_ptr = desp;

				*desp++ = s[i];
			}

			last_nonspace_char_ptr[1] = 0;	// put a string terminator right after
		}
	}
}

/*
//==================================================================
void TStrFilenameFromPath( TCHAR *s )
{
	bool has_backslash = (TStrFindLastOf( s, _TXCHAR('\\') ) >= 0);
	bool has_slash = (TStrFindLastOf( s, _TXCHAR('/') ) >= 0);

	if ( has_slash )
		TStrRemoveUntilLastOf( s, _TXCHAR('/') );
	else
		TStrRemoveUntilLastOf( s, _TXCHAR('\\') );
}
*/

//==================================================================
tstring TStrFilenameFromPath( const tstring &s )
{
	size_t	slash_pos = s.find_last_of( _TXCHAR('/') );
	size_t	bslash_pos = s.find_last_of( _TXCHAR('\\') );

	bool has_slash = (slash_pos != tstring::npos);
	bool has_bslash = (bslash_pos != tstring::npos);

	if ( has_slash )
	{
		if ( slash_pos == s.length()-1 )
			return tstring();	// trailing slash returns an empty string

		return tstring( &s[ slash_pos+1 ] );
	}
	else
	if ( has_bslash )
	{
		if ( bslash_pos == s.length()-1 )
			return tstring();	// trailing backslash returns an empty string

		return tstring( &s[ bslash_pos+1 ] );
	}
	else
		return tstring();
}

//==================================================================
const TCHAR *TStrGetFilenameExtension( const TCHAR *fnamep )
{
	int	idx = TStrFindLastOf( fnamep, _TXCHAR('.') );

	if ( idx < 0 )
		return fnamep + _tcslen( fnamep );
	else
		return fnamep + idx + 1;
}


//==================================================================
int TStrFindLastOf( const TCHAR *s, TCHAR find_ch )
{
	size_t		len = _tcslen( s );

	for (size_t i=len; i > 0; --i)
	{
		if ( s[i-1] == find_ch )	// head previous spaces
		{
			return i-1;
		}
	}

	return -1;
}

//==================================================================
void TStrRemoveUntilLastOf( TCHAR *s, TCHAR find_ch )
{
	int	last_occurrence = TStrFindLastOf( s, find_ch );

	if ( last_occurrence >= 0 )
	{
		size_t	len = _tcslen( s );

		for (size_t i=0; i < len; ++i)
		{
			s[i] = s[i+last_occurrence+1];
		}
	}
}

//==================================================================
TCHAR *MByteToTCHAR( u_int mbtype, const char *in_ansip )
{
	if NOT( in_ansip )
		return NULL;

	// special case: empty string returns directly an empty string
	if ( strlen( in_ansip ) == 0 )
	{
		TCHAR	*outbuff = new TCHAR[ 1 ];
		outbuff[0] = 0;
		
		return outbuff;
	}

#ifdef UNICODE
	u_int	outbuff_size = MultiByteToWideChar( mbtype, 0, in_ansip, -1, NULL, 0 );

	TCHAR	*outbuff = new TCHAR[ outbuff_size ];

	if ( MultiByteToWideChar( mbtype, 0, in_ansip, -1, outbuff, outbuff_size ) == 0 )
	{
		PASSERT( 0 );
		delete [] outbuff;

		return NULL;
	}
#else
	
	u_int	outbuff_size = strlen( in_ansip );

	char	*outbuff = new char [outbuff_size];

	_tcscpy_s( outbuff, outbuff_size, in_ansip );

#endif

	return outbuff;
}

//==================================================================
TCHAR *ANSIToTCHAR( const char *in_ansip )
{
	return MByteToTCHAR( CP_ACP, in_ansip );
}

//==================================================================
TCHAR *UTF8ToTCHAR( const char *in_utf8p )
{
	return MByteToTCHAR( CP_UTF8, in_utf8p );
}

//==================================================================
char *TCHARToMByte( u_int mbtype, const TCHAR *in_tcharp )
{
	if NOT( in_tcharp )
		return NULL;

	char	*outbuffp = NULL;
	u_int	outbuff_size = 0;

#ifdef UNICODE
	outbuff_size = WideCharToMultiByte( mbtype, 0, in_tcharp, -1, NULL, 0, NULL, 0 );

	outbuffp = new char[ outbuff_size ];

	if ( WideCharToMultiByte( mbtype, 0, in_tcharp, -1, outbuffp, outbuff_size, NULL, 0 ) == 0 )
	{
		PASSERT( 0 );
		delete [] outbuffp;

		return NULL;
	}
#else

	outbuff_size = strlen( in_tcharp );

	outbuffp = new char [ outbuff_size ];

	_tcscpy_s( outbuffp, outbuff_size, in_ansip );

#endif

	return outbuffp;
}

//==================================================================
char *TCHARToANSI( const TCHAR *in_tcharp )
{
	return TCHARToMByte( CP_ACP, in_tcharp );
}
//==================================================================
char *TCHARToUTF8( const TCHAR *in_tcharp )
{
	return TCHARToMByte( CP_UTF8, in_tcharp );
}

//==================================================================
}
